/*
 * 68k_registers.hpp
 *
 *  Created on: Nov 4, 2011
 *      Author: dgdiniz
 */

#ifndef SG8K_REGISTERS_HPP_
#define SG8K_REGISTERS_HPP_

struct flag_t
{
	bool t, s, i2, i1, i0, x, n, z, v, c;
	uint8 lmask;

	inline operator unsigned() const
	{
		return (t << 15) + (s << 13) + (i2 << 10) + (i1 << 9) + (i0 << 8) + (x << 4) + (n << 3) + (z << 2) + (v << 1) + (c << 0);
	}

	inline unsigned operator=(uint16 data)
	{
		t = data & 0x8000; s = data & 0x2000; i2 = data & 0x0400; i1 = data & 0x0200; i0 = data & 0x0100;
		x = data & 0x0010; n = data & 0x0008;  z = data & 0x0004;  v = data & 0x0002;  c = data & 0x0001;
		return data;
	}

	inline unsigned operator|=(unsigned data) { return operator=(operator unsigned() | data); }
	inline unsigned operator^=(unsigned data) { return operator=(operator unsigned() ^ data); }
	inline unsigned operator&=(unsigned data) { return operator=(operator unsigned() & data); }
};

struct reg32_t
{
	union
	{
		uint32 l;
		struct{ uint16 wh,w; };
		struct{ uint8 wbh,wb,bh,b; };
	};

	inline operator unsigned() const { return l; }
	inline unsigned operator   = (unsigned i) { return l   = i; }
	inline unsigned operator  |= (unsigned i) { return l  |= i; }
	inline unsigned operator  ^= (unsigned i) { return l  ^= i; }
	inline unsigned operator  &= (unsigned i) { return l  &= i; }
	inline unsigned operator <<= (unsigned i) { return l <<= i; }
	inline unsigned operator >>= (unsigned i) { return l >>= i; }
	inline unsigned operator  += (unsigned i) { return l  += i; }
	inline unsigned operator  -= (unsigned i) { return l  -= i; }
	inline unsigned operator  *= (unsigned i) { return l  *= i; }
	inline unsigned operator  /= (unsigned i) { return l  /= i; }
	inline unsigned operator  %= (unsigned i) { return l  %= i; }

	reg32_t(): l(0) {}
};

struct reg24_t
{
	union
	{
		uint32 l;
		struct{ uint16 wh,w; };
	};

	//The uclip<24> is to keep the upper byte always 0.
	inline operator unsigned() const { return l; }
	inline unsigned operator   = (unsigned i) { return l = uclip<24>(i); }
	inline unsigned operator  |= (unsigned i) { return l = uclip<24>(l  | i); }
	inline unsigned operator  ^= (unsigned i) { return l = uclip<24>(l  ^ i); }
	inline unsigned operator  &= (unsigned i) { return l = uclip<24>(l  & i); }
	inline unsigned operator <<= (unsigned i) { return l = uclip<24>(l << i); }
	inline unsigned operator >>= (unsigned i) { return l = uclip<24>(l >> i); }
	inline unsigned operator  += (unsigned i) { return l = uclip<24>(l  + i); }
	inline unsigned operator  -= (unsigned i) { return l = uclip<24>(l  - i); }
	inline unsigned operator  *= (unsigned i) { return l = uclip<24>(l  * i); }
	inline unsigned operator  /= (unsigned i) { return l = uclip<24>(l  / i); }
	inline unsigned operator  %= (unsigned i) { return l = uclip<24>(l  % i); }

	reg24_t(): l(0) {}
};

struct regs_t
{
	reg24_t a[9], &A0, &A1, &A2, &A3, &A4, &A5, &A6, &A7;
	reg32_t d[8], &D0, &D1, &D2, &D3, &D4, &D5, &D6, &D7;
	reg24_t pc;
	flag_t  SR;
	reg24_t &USP, &SSP; //User and Supervisor Stack Pointer.


	regs_t(): A0(a[0]), A1(a[1]), A2(a[2]), A3(a[3]), A4(a[4]), A5(a[5]), A6(a[6]), A7(a[8]),
			  D0(a[0]), D1(a[1]), D2(a[2]), D3(a[3]), D4(a[4]), D5(a[5]), D6(a[6]), D7(a[7]),
			  USP(a[7]), SSP(a[8])
	{
		//initialize the registers here (post creation).
	}
};



#endif /* 68K_REGISTERS_HPP_ */
